package com.info3k.client.components;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.TextBox;
import com.info3k.client.Info3K;
import com.info3k.client.Info3KService;
import com.info3k.client.Info3KServiceAsync;
import com.info3k.client.commands.MainCommand;
import com.info3k.client.commands.user.EditUserCommand;
import com.info3k.client.commands.user.RecoverPasswordCommand;
import com.info3k.client.domain.User;

public class LoginManager extends Composite {
	 
	private RegisterManager registerManager;
	
 	private FormPanel formPanel = new FormPanel();
 	
 	private Button logoutButton = new Button(Info3K.msgs.logout());
 	private Button loginButton = new Button(Info3K.msgs.login());
 	private Button settingsButton = new Button(Info3K.msgs.settings());
	private FlowPanel panelInForm = new FlowPanel();
	
    private Button registerButton = new Button(Info3K.msgs.register());
    
    private PasswordTextBox password = new PasswordTextBox();
    private Label labelPassword = new Label();
    private TextBox username = new TextBox();
    private Label welcome = new Label();
    private Label label = new Label();
    private HTML forgotPassword = new HTML("<div style=\"float: right; margin-right: 20px\">" + Info3K.msgs.forgotPassword() + "</div>");
 	
 	private User user;
 	private Info3K info3k;
 	
 	private Info3KServiceAsync infoService = GWT.create(Info3KService.class);
	
	public LoginManager(Info3K info){	        	        
		this.info3k = info;
		
		registerManager = new RegisterManager(info);
		
		final FlowPanel panel = new FlowPanel();
        initWidget(panel);
        panel.setStylePrimaryName("login_manager");
	 	
        formPanel.setAction("");
        formPanel.setMethod(FormPanel.METHOD_POST);
        
        label.setStylePrimaryName("info3k_label");
        label.setText(Info3K.msgs.username() + ":");
        
        welcome.setStylePrimaryName("info3k_label");
        
        username.setName("q");
        username.setValue(Info3K.msgs.username());
        username.setStylePrimaryName("field");
        username.setTitle(Info3K.msgs.username());
        
        username.addBlurHandler(new BlurHandler(){
			public void onBlur(BlurEvent event) {
				if(username.getText().equals(""))
					username.setText(Info3K.msgs.username());
				else if(username.getText().equals(Info3K.msgs.username()))
					username.setText("");
			}
        });
        
        username.addFocusHandler(new FocusHandler(){
			public void onFocus(FocusEvent event) {
				if(username.getText().equals(""))
					username.setText(Info3K.msgs.username());
				else if(username.getText().equals(Info3K.msgs.username()))
					username.setText("");
			}
        });
               
        labelPassword.setStylePrimaryName("info3k_label");
        labelPassword.setText(Info3K.msgs.password() + ":");
        
        password.setName("q");
        password.setValue(Info3K.msgs.password());
        password.setStylePrimaryName("field");
        password.setTitle(Info3K.msgs.password());
        
        password.addBlurHandler(new BlurHandler(){
			public void onBlur(BlurEvent event) {
				if(password.getText().equals(""))
					password.setText(Info3K.msgs.password());
				else if(password.getText().equals(Info3K.msgs.password()))
					password.setText("");
			}
        });
        
        password.addFocusHandler(new FocusHandler(){
			public void onFocus(FocusEvent event) {
				if(password.getText().equals(""))
					password.setText(Info3K.msgs.password());
				else if(password.getText().equals(Info3K.msgs.password()))
					password.setText("");
			}
        });
        
        password.addKeyPressHandler(new KeyPressHandler(){

			public void onKeyPress(KeyPressEvent event) {
				if(event.getCharCode() == 13){
					logIn();
				}
			}
        	
        });
        
        forgotPassword.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event) {
				RecoverPasswordCommand cmd = new RecoverPasswordCommand(info3k);
				cmd.execute();
			}
        });
        
        registerButton.setTitle(Info3K.msgs.register());
        registerButton.setStylePrimaryName("button");
        
        registerButton.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event) {
				registerManager = new RegisterManager(info3k);
				registerManager.center();
			}
        });
        
        logoutButton.setTitle(Info3K.msgs.logout());
        logoutButton.setStylePrimaryName("button");
        
        settingsButton.setStylePrimaryName("button");
        
        settingsButton.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event) {
				EditUserCommand cmd = new EditUserCommand(info3k, user);
				cmd.execute();
			}
        });
        
        logoutButton.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event) {
				Info3K.loader.setVisible(true);
				infoService.logOutUser(user, new AsyncCallback<Boolean>(){
					public void onFailure(Throwable caught) {
						Info3K.loader.setVisible(false);
						InfoWindow.showMessage(Info3K.msgs.error(), caught.getMessage());
					}

					public void onSuccess(Boolean result) {
						Info3K.loader.setVisible(false);
						if(result){
							InfoWindow.showMessage(Info3K.msgs.ok(), Info3K.msgs.loggedOutSuccessfully(user.getUsername()));
				        	panelInForm.clear();
					        panelInForm.add(label);
					        panelInForm.add(username);
					        panelInForm.add(labelPassword);
					        panelInForm.add(password);
					        panelInForm.add(loginButton);
					        panelInForm.add(registerButton);
					        panelInForm.add(forgotPassword);
					        user = null;
					        info3k.getMenuManager().renderMenus();
							MainCommand main = new MainCommand("../pages/main.html");
							main.execute();
				        }
					}
				});
			}
        });
                
        loginButton.setTitle(Info3K.msgs.login());
        loginButton.setStylePrimaryName("button");
        loginButton.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event) {
				logIn();
			}
        });
                
        formPanel.add(panelInForm);
        panel.add(formPanel);
        
        forgotPassword.getElement().getStyle().setProperty("cursor", "pointer");
        
		infoService.checkIfLogged(new AsyncCallback<User>(){
			public void onFailure(Throwable caught) {
				InfoWindow.showMessage(Info3K.msgs.error(), caught.getMessage());
			}

			public void onSuccess(User result) {
				if(result!=null){
					user = result;
					welcome.setText(Info3K.msgs.welcome(result.getUsername()));
					panelInForm.add(welcome);
					panelInForm.add(settingsButton);
					panelInForm.add(logoutButton);
					info3k.getMenuManager().renderMenus();
				} else {
			        panelInForm.add(label);
			        panelInForm.add(username);
			        panelInForm.add(labelPassword);
			        panelInForm.add(password);
			        panelInForm.add(loginButton);
			        panelInForm.add(registerButton);
			        panelInForm.add(forgotPassword);
				}
			}
		});
	}
	
    private void logIn(){
		if(username.getText().length()>0 && !username.getText().equals(Info3K.msgs.username()) && password.getText().length()>6){
			Info3K.loader.setVisible(true);
			infoService.logInUser(username.getText(), password.getText(), new AsyncCallback<User>(){
				public void onFailure(Throwable caught) {
					Info3K.loader.setVisible(false);
					InfoWindow.showMessage(Info3K.msgs.error(), caught.getMessage());
				}

				public void onSuccess(User result) {
					Info3K.loader.setVisible(false);
					if(result!=null){
						user = result;
						panelInForm.clear();
						welcome.setText(Info3K.msgs.welcome(result.getUsername()));
						panelInForm.add(welcome);
						panelInForm.add(settingsButton);
						panelInForm.add(logoutButton);
			        	username.setText(Info3K.msgs.username());
			        	password.setText(Info3K.msgs.password());
						InfoWindow.showMessage(Info3K.msgs.ok(), Info3K.msgs.loggedInSuccessfully(result.getUsername()));
						info3k.getMenuManager().renderMenus();
						MainCommand main = new MainCommand("../pages/main.html");
						main.execute();
			        } else {
			        	username.setText(Info3K.msgs.username());
			        	password.setText(Info3K.msgs.password());
			        	InfoWindow.showMessage(Info3K.msgs.error(), Info3K.msgs.incorrectUsernameOrPassword());
			        }
				}
				
			});
		} else {
			if(username.getText().length()==0 || username.getText().equals(Info3K.msgs.username())) InfoWindow.showMessage(Info3K.msgs.error(), Info3K.msgs.enterUsername());
			else if(password.getText().length()<=6) InfoWindow.showMessage(Info3K.msgs.error(), Info3K.msgs.passwordNotValid());
		}
    }
 	
    public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public void setInfo3k(Info3K info3k) {
		this.info3k = info3k;
	}

	public Info3K getInfo3k() {
		return info3k;
	}
}